// locutor
// (c) 2009-2010, Normen Müller, normen.mueller@gmail.com  
// $Id: Base.scala 94 2010-06-12 15:35:36Z normen.mueller $
package locutor.util.parsing

import collection.mutable.HashSet

import scala.util.parsing.combinator._
import scala.util.parsing.combinator.syntactical._

/** Companion to <code>BaseParser</code> class.
 * 
 *  @author <a href="mailto:normen.mueller@googlemail.com">Normen M&#xFC;ller</a>
 *  @version 0.0.5
 */
private [locutor] object BaseParser {  
  val reserved = new HashSet[String] ++ List("true", "false", "null", "boolean", "int", "float", "double", "string", "object")
  
  val delimiters = new HashSet[String] ++ List("[", "]", ",", ":", "=", "*", "+")  
}

/** Base of locutor parsers.
 * 
 *  @author <a href="mailto:normen.mueller@googlemail.com">Normen M&#xFC;ller</a>
 *  @version 0.0.5
 */
private [locutor] trait BaseParser extends StdTokenParsers with ImplicitConversions {

  lazy val text = (ident | string)

  lazy val range = "[" ~> ( "*" ^^^ {"[*]"} | "+" ^^^ {"[+]"} | numeric ~ opt(":" ~> ("*" | numeric)) ^^ {
    case l ~ Some(r) => "["+l+":"+r+"]"
    case l ~ None    => "["+l+"]"
  }) <~ "]"

  //@todo add hexadecimals  
  lazy val constant = numeric | string | "true" | "false" | "null"

  lazy val primitives = "boolean" | "int" | "float" | "double" | "string" | "object"
  
  lazy val string = accept("string",  {case lexical.StringLit(n) => n})
  
  lazy val numeric = accept("numeric", {case lexical.NumericLit(n) => n})

  def ∑(o: Option[String]) = o match {case Some(s) => s case None => ""}
  
  def ∑(l: List[String]) = l match {case Nil => "" case _ => l mkString}
}
